package com.ltxtiyu.video.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.ltxtiyu.video.bean.MessageInfoBean;
import com.ltxtiyu.video.cacheDao.ConfigCacheDao;
import com.ltxtiyu.video.cacheDao.UserCacheDao;
import com.ltxtiyu.video.common.CodeTypeConstant;
import com.ltxtiyu.video.common.ConfigConstant;
import com.ltxtiyu.video.common.JsonTool;
import com.ltxtiyu.video.common.RetEnum;
import com.ltxtiyu.video.dao.ltx.*;
import com.ltxtiyu.video.entity.*;
import com.ltxtiyu.video.service.app.UserService;
import com.ltxtiyu.video.tool.AliTool;
import com.ltxtiyu.video.tool.ObjectTool;
import com.ltxtiyu.video.tool.StringTool;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;

@Service
@Transactional
public class UserServiceImpl implements UserService{
    public static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);
    @Autowired
    AmqpTemplate amqpTemplate;

    @Autowired
    UserDao userDao;
    @Autowired
    UserCacheDao userCacheDao;
    @Autowired
    AreaDao areaDao;
    @Autowired
    ConfigCacheDao configCacheDao;
    @Autowired
    MessageDao messageDao;
    @Autowired
    UserFollowDao userFollowDao;
    @Autowired
    MomentDao momentDao;
    @Autowired
    MomentCountDao momentCountDao;
    @Autowired
    FeedbackDao feedbackDao;

    @Override
    public User selectByPrimaryKey(Integer userId) {
        return userCacheDao.selectByPrimaryKey(userId);
    }

    /**
     * 我的设置
     * @param params
     * @return
     */
    @Override
    public String mySetting(Map<String, String> params) {
        Integer userId = Integer.parseInt(params.get("userId"));
        User user = userCacheDao.selectByPrimaryKey(userId);
        if(user == null){   // 用户不存在
            return JsonTool.genJson(RetEnum.OAUTH_CHECK_INEXISTENCE);
        }
        Integer hasBanding = 0;
        Integer hasPassword = 0;
        if(StringUtils.isNotBlank(user.getMobile())){   // 是否绑定
            hasBanding = 1;
        }
        if(StringUtils.isNotBlank(user.getPassword())){ // 是否设置密码
            hasPassword = 1;
        }
        Map<String, Object> result = new HashMap<>();
        result.put("hasBanding",hasBanding);
        result.put("hasPassword",hasPassword);
        result.put("mobile",hasBanding.intValue() == 1 ? user.getMobile() : "");
        return JsonTool.genJson(RetEnum.SUCCESS,result);
    }

    /**
     * 我的个人资料
     * @param params
     * @return
     */
    @Override
    public String myProfile(Map<String, String> params) {
        Integer userId = Integer.parseInt(params.get("userId"));
        User user = userCacheDao.selectByPrimaryKey(userId);
        if(user == null){   // 用户不存在
            return JsonTool.genJson(RetEnum.OAUTH_CHECK_INEXISTENCE);
        }
        Map<String, Object> result = new HashMap<>();
        result.put("nickName",user.getNickName());
        result.put("gender",user.getGender());
        result.put("birthDate",user.getBirthDate());
        result.put("province",user.getResidenceProvince());
        result.put("city",user.getResidenceCity());
        String provinceName = "";
        String cityName = "";
        String headPortraitUrl = "";
        if(user.getResidenceProvince() != null){    // 获取省市名称
            provinceName = areaDao.selectByPrimaryKey(user.getResidenceProvince()).getName();
        }
        if(user.getResidenceCity() != null){
            cityName = areaDao.selectByPrimaryKey(user.getResidenceCity()).getName();
        }
        if(StringUtils.isNotBlank(user.getHeadPortraitId())){   // 获取头像地址
            // 获取图片alitool
            String OSS_CDN = configCacheDao.selectByCkey(ConfigConstant.OSS_CDN).getCvalue();
            String ACCESS_ID = configCacheDao.selectByCkey(ConfigConstant.ACCESS_ID).getCvalue();
            String ACCESS_KEY = configCacheDao.selectByCkey(ConfigConstant.ACCESS_KEY).getCvalue();
            String BUCKET_ID = configCacheDao.selectByCkey(ConfigConstant.BUCKET_ID).getCvalue();
            // 查看图片用OSS_CDN
            AliTool aliTool = AliTool.getInstance(OSS_CDN, ACCESS_ID, ACCESS_KEY, BUCKET_ID);
            headPortraitUrl = aliTool.getAccessURL(user.getHeadPortraitId());
        }
        result.put("provinceName",provinceName);
        result.put("cityName",cityName);
        result.put("headPortraitUrl",headPortraitUrl);
        return JsonTool.genJson(RetEnum.SUCCESS,result);
    }

    /**
     * 修改个人资料
     * @param params
     * @return
     */
    @Override
    public String updateMyInfo(Map<String, String> params) {
        Integer userId = Integer.parseInt(params.get("userId"));
        String headPortraitPic = ObjectTool.stringOrNull(params.get("headPortraitPic"));
        String nickName = ObjectTool.stringOrNull(params.get("nickName"));
        String birthDate = ObjectTool.stringOrNull(params.get("birthDate"));
        Integer gender = ObjectTool.numberOrNull(params.get("gender"));
        Integer province = ObjectTool.numberOrNull(params.get("province"));
        Integer city = ObjectTool.numberOrNull(params.get("city"));

        User user = userCacheDao.selectByPrimaryKey(userId);
        if(user == null){   // 用户不存在
            return JsonTool.genJson(RetEnum.OAUTH_CHECK_INEXISTENCE);
        }

        /**
         * 输入文本过长
         * 指得是字符, 汉字,数字,字母都是1个字符,
         * mysql5以后vachar(n)也指的是字符
         */
        if(nickName != null && nickName.length() > 20){     // 输入文本过长,指得是字符, 汉字,数字,字母都是1个字符, mysql5以后vachar(n)也指的是字符
            return JsonTool.genJson(RetEnum.REQUEST_INPUT_TEXT_LENGTH_TOO_LONG);
        }

        String OSS_ENDPOINT = configCacheDao.selectByCkey(ConfigConstant.OSS_ENDPOINT).getCvalue();
        String ACCESS_ID = configCacheDao.selectByCkey(ConfigConstant.ACCESS_ID).getCvalue();
        String ACCESS_KEY = configCacheDao.selectByCkey(ConfigConstant.ACCESS_KEY).getCvalue();
        String BUCKET_ID = configCacheDao.selectByCkey(ConfigConstant.BUCKET_ID).getCvalue();
        String OSS_CDN = configCacheDao.selectByCkey(ConfigConstant.OSS_CDN).getCvalue();
        // 上传图片用OSS_ENDPOINT
        AliTool aliTool = AliTool.getInstance(OSS_ENDPOINT, ACCESS_ID, ACCESS_KEY, BUCKET_ID);
        // 查看图片用OSS_CDN
        AliTool showAliTool = AliTool.getInstance(OSS_CDN, ACCESS_ID, ACCESS_KEY, BUCKET_ID);
        if(StringUtils.isNotBlank(headPortraitPic)){   // 获取头像地址
            String headPortrait = aliTool.updateSinglePic(aliTool, headPortraitPic);
            user.setHeadPortraitId(headPortrait);
        }
        if(nickName != null){   // 防止cache存null
            user.setNickName(nickName);
        }
        if(birthDate != null){
            user.setBirthDate(StringTool.stringToDate(birthDate));
        }
        if(gender != null){
            user.setGender(gender);
        }
        if(province != null){
            user.setResidenceProvince(province);
        }
        if(city != null){
            user.setResidenceCity(city);
        }

        userCacheDao.updateByPrimaryKeySelective(user);

        // 封装返回数据
        Map<String, Object> result = new HashMap<>();
        result.put("nickName",user.getNickName());
        result.put("gender",user.getGender());
        result.put("birthDate",user.getBirthDate());
        result.put("province",user.getResidenceProvince());
        result.put("city",user.getResidenceCity());
        String provinceName = "";
        String cityName = "";
        String headPortraitUrl = "";
        if(user.getResidenceProvince() != null){    // 获取省市名称
            provinceName = areaDao.selectByPrimaryKey(user.getResidenceProvince()).getName();
        }
        if(user.getResidenceCity() != null){
            cityName = areaDao.selectByPrimaryKey(user.getResidenceCity()).getName();
        }
        if(StringUtils.isNotBlank(user.getHeadPortraitId())){   // 获取头像地址
            headPortraitUrl = showAliTool.getAccessURL(user.getHeadPortraitId());
        }
        result.put("provinceName",provinceName);
        result.put("cityName",cityName);
        result.put("headPortraitUrl",headPortraitUrl);
        return JsonTool.genJson(RetEnum.SUCCESS,result);
    }

    /**
     * 我的首页 | 查看他人首页
     * @param params
     * @return
     */
    @Override
    public String userIndex(Map<String, String> params) {
        Integer userId = Integer.parseInt(params.get("userId"));    // 当前登录用户
        Integer beViewUserId = ObjectTool.numberOrNull(params.get("beViewUserId"));     // 被查询用户id, 自己查看自己不传
        Integer resultBeViewUserId = -1;
        if(userId.intValue() < 1 && beViewUserId == null){
            return JsonTool.genJson(RetEnum.REQUEST_PARAM_ERROR);   // 请求参数错误
        }
        if(beViewUserId == null){
            beViewUserId = userId;  // 转换查询用户id
        }else {
            resultBeViewUserId = beViewUserId;      // 前段需要返回beViewUserId
        }

        Integer isSelf = 0;
        if(userId.intValue() > 0 && (beViewUserId == null || beViewUserId.equals(userId))){  // 自己查自己
            isSelf = 1;
        }
        User beViewUser = userCacheDao.selectByPrimaryKey(beViewUserId);
        if(beViewUser == null){ // 查询的用户不存在
            return JsonTool.genJson(RetEnum.USER_VIEW_IS_NOT_EXIST);
        }

        Map<String, Object> result = new HashMap<>();
        String provinceName = "";
        String cityName = "";
        String headPortraitUrl = "";
        if(beViewUser.getResidenceProvince() != null){    // 获取省市名称
            provinceName = areaDao.selectByPrimaryKey(beViewUser.getResidenceProvince()).getName();
        }
        if(beViewUser.getResidenceCity() != null){
            cityName = areaDao.selectByPrimaryKey(beViewUser.getResidenceCity()).getName();
        }
        if(StringUtils.isNotBlank(beViewUser.getHeadPortraitId())){   // 获取头像地址
            // 获取图片alitool
            String OSS_CDN = configCacheDao.selectByCkey(ConfigConstant.OSS_CDN).getCvalue();
            String ACCESS_ID = configCacheDao.selectByCkey(ConfigConstant.ACCESS_ID).getCvalue();
            String ACCESS_KEY = configCacheDao.selectByCkey(ConfigConstant.ACCESS_KEY).getCvalue();
            String BUCKET_ID = configCacheDao.selectByCkey(ConfigConstant.BUCKET_ID).getCvalue();
            // 查看图片用OSS_CDN
            AliTool aliTool = AliTool.getInstance(OSS_CDN, ACCESS_ID, ACCESS_KEY, BUCKET_ID);
            headPortraitUrl = aliTool.getAccessURL(beViewUser.getHeadPortraitId());
        }

        // 默认值查看公开的作品
        Integer isFollow = 0;
        // 查询是否关注
        if(userId.intValue() > 0 && !userId.equals(beViewUserId)){   // 用户登录并且是查看别人
            Map<String, Object> map = new HashMap<>();
            map.put("userId",beViewUserId);
            map.put("followerId",userId);
            List<UserFollow> userFollows = userFollowDao.selectHasFollow(map);
            if(userFollows.size() > 0){ // 有关注关系
                isFollow = 1;
            }
        }

        // 默认值查看公开的作品
        Map<String, Object> momentMap = new HashMap<>();
        momentMap.put("userId",beViewUserId);
        List<Integer> permissionTypes = new ArrayList<>();
        permissionTypes.add(CodeTypeConstant.MOMENT_PERMISSION_TYPE_110);   // 公开

        if(isSelf.intValue() > 0){ // 自己查自己, 公开|好友|私密都会查出来
            permissionTypes.add(CodeTypeConstant.MOMENT_PERMISSION_TYPE_111);   // 好友
            permissionTypes.add(CodeTypeConstant.MOMENT_PERMISSION_TYPE_112);   // 私密
        }else if(userId.intValue() > 0 && !userId.equals(beViewUserId)) {   // 用户登录并且是查看别人
            Map<String, Object> map = new HashMap<>();
            map.put("userId",userId);
            map.put("followerId",beViewUserId);
            List<UserFollow> userFollows = userFollowDao.selectHasFollow(map);
            if(userFollows.size() > 0 && isFollow.intValue() > 0) {   // 两个人是好友关系
                permissionTypes.add(CodeTypeConstant.MOMENT_PERMISSION_TYPE_111);   // 好友
            }
        }
        momentMap.put("permissionTypes", permissionTypes);

        Integer messageCount = 0;
        if(isSelf.intValue() == 1){   // 用户登录,并且是自己查看自己
            // 查询消息总数
            messageCount = messageDao.selectUnReadCount(userId);
        }
        // 被查询人的关注数量
        Integer focusCount = userFollowDao.selectFocusCount(beViewUserId);
        // 被查询人的粉丝数量
        Integer followerCount = userFollowDao.selectFollowerCount(beViewUserId);

        // 查询作品数量
        Integer momentCount = momentDao.selectMomentCountForPerson(momentMap);

        /**
         * 查询点赞数量
         * 只查点赞的公开作品
         */
        momentMap.clear();
        momentMap.put("userId",beViewUserId);
        permissionTypes.clear();
        permissionTypes.add(CodeTypeConstant.MOMENT_PERMISSION_TYPE_110);   // 公开
        /*if(userId.intValue() > 0 && !userId.equals(beViewUserId)) {   // 用户登录并且是查看别人
            Map<String, Object> map = new HashMap<>();
            map.put("userId",userId);
            map.put("followerId",beViewUserId);
            List<UserFollow> userFollows = userFollowDao.selectHasFollow(map);
            if(userFollows.size() > 0 && isFollow.intValue() > 0) {   // 两个人是好友关系
                permissionTypes.add(CodeTypeConstant.MOMENT_PERMISSION_TYPE_111);   // 好友
            }
        }*/
        momentMap.put("permissionTypes", permissionTypes);
        Integer likedCount = momentDao.selectLikedMomentCount(momentMap);
        // 查询被点赞数量
        Integer beLikeCount = momentCountDao.selectSumBeLikedMomentCount(beViewUserId);

        result.put("nickName",beViewUser.getNickName());
        result.put("provinceName",provinceName);
        result.put("cityName",cityName);
        result.put("headPortraitUrl",headPortraitUrl);
        result.put("isFollow",isFollow);
        result.put("messageCount",messageCount);
        result.put("focusCount",focusCount);
        result.put("followerCount",followerCount);
        result.put("momentCount",momentCount);
        result.put("likedCount",likedCount);
        result.put("beLikeCount",beLikeCount);
        result.put("beViewUserId",resultBeViewUserId);
        return JsonTool.genJson(RetEnum.SUCCESS,result);
    }

    /**
     * 关注用户
     * @param params
     * @return
     */
    @Override
    public String follow(Map<String, String> params) {
        Integer userId = Integer.parseInt(params.get("userId"));
        Integer focusUserId = ObjectTool.numberOrNull(params.get("focusUserId"));
        if(focusUserId == null){
            return JsonTool.genJson(RetEnum.REQUEST_PARAM_ERROR);
        }
        if(userId.equals(focusUserId)){
            return JsonTool.genJson(RetEnum.MOMENT_FOLLOW_ERROR);   // 不能关注自己
        }
        User focusUser = userCacheDao.selectByPrimaryKey(focusUserId);
        if(focusUser == null){
            return JsonTool.genJson(RetEnum.OAUTH_CHECK_INEXISTENCE);   // 用户不存在
        }
        if(focusUser.getStatus().intValue() == 0){
            return JsonTool.genJson(RetEnum.OAUTH_CHECK_BANNED);    // 用户被封停
        }

        User followUser = userCacheDao.selectByPrimaryKey(userId);
        String nickName = "";
        if(followUser != null && StringUtils.isNotBlank(followUser.getNickName())){
            nickName = followUser.getNickName();
        }

        Map<String, Object> map = new HashMap<>();
        map.put("userId",focusUserId);  // 注意身份角色不同
        map.put("followerId",userId);
        List<UserFollow> tempUserFollows = userFollowDao.selectHasFollow(map);
        if(tempUserFollows.size() < 1){ // 说明没有被关注, 查询一次防止脏数据
            UserFollow userFollow = new UserFollow();
            userFollow.setFollowerId(userId);
            userFollow.setUserId(focusUserId);
            userFollow.setCreateTime(new Date());
            userFollowDao.insertSelective(userFollow);

            // 封装消息内容
            MessageInfoBean bean = new MessageInfoBean();
            bean.setBeOperateObjectId(focusUserId);
            bean.setMessageBody("关注了你");
    //        bean.setVideoId(-1);  // 关注的videoCover为空字符串
            bean.setSenderId(userId);
            bean.setSenderNickName(nickName);
            if(StringUtils.isNotBlank(followUser.getHeadPortraitId())){
                bean.setSenderHeadPortraitId(followUser.getHeadPortraitId());
            }

            // 添加消息
            Message message = new Message();
            message.setReceiver(focusUserId);
            message.setCreateTime(new Date());
            message.setType(CodeTypeConstant.MESSAGE_CONTENT_TYPE_123); // 粉丝
            message.setCotnent(JSON.toJSONString(bean));
            messageDao.insertSelective(message);

            // 消息队列发送消息
            Map<String, Object> messageBody = new HashMap<>();
            Map<String, String> fields = new HashMap<>();
            fields.put("nickName",nickName);      // 跟随者的昵称
            fields.put("type",CodeTypeConstant.PUSH_MESSAGE_APP_TYPE_1000+"");
            messageBody.put("content",ConfigConstant.PUSH_MESSAGE_APP_CONTENT_FOLLOW);
            messageBody.put("fields",fields);
            messageBody.put("deviceTokens", focusUser.getDeviceToken());
            if(focusUser != null && StringUtils.isNotBlank(focusUser.getDeviceToken())){  // 被关注者
                amqpTemplate.convertAndSend(ConfigConstant.MESSAGE_NAME_APP_PUSH_MEASSGE,messageBody);
                LOGGER.info(">>>>>>>>>>>>>>>关注-推送消息发出队列,参数:{}",messageBody.toString());
            }
        }


        return JsonTool.genJson(RetEnum.SUCCESS);
    }

    /**
     * 取消关注
     * @param params
     * @return
     */
    @Override
    public String unfollow(Map<String, String> params) {
        Integer userId = Integer.parseInt(params.get("userId"));
        Integer focusUserId = ObjectTool.numberOrNull(params.get("focusUserId"));
        if(focusUserId == null){
            return JsonTool.genJson(RetEnum.REQUEST_PARAM_ERROR);
        }
        User user = userCacheDao.selectByPrimaryKey(focusUserId);
        if(user == null){
            return JsonTool.genJson(RetEnum.OAUTH_CHECK_INEXISTENCE);   // 用户不存在
        }
        Map<String, Object> map = new HashMap<>();
        map.put("userId",focusUserId);  // 注意身份角色不同
        map.put("followerId",userId);
        List<UserFollow> tempUserFollows = userFollowDao.selectHasFollow(map);
        for(UserFollow follow : tempUserFollows){   // 删除
            userFollowDao.deleteByPrimaryKey(follow.getId());
        }
        return JsonTool.genJson(RetEnum.SUCCESS);
    }

    /**
     * 添加意见反馈
     * @param params
     * @return
     */
    @Override
    public String addFeedback(Map<String, String> params) {
        Integer userId = Integer.parseInt(params.get("userId"));
        String content = ObjectTool.stringOrNull(params.get("content"));
        if(StringUtils.isBlank(content)){
            return JsonTool.genJson(RetEnum.REQUEST_PARAM_ERROR);
        }
        Feedback feedback = new Feedback();
        feedback.setContentText(content);
        feedback.setSender(userId);
        feedback.setCreateTime(new Date());
        feedbackDao.insertSelective(feedback);
        return JsonTool.genJson(RetEnum.SUCCESS);
    }

    /**
     * 我的好友列表
     * @param params
     * @return
     */
    @Override
    public String listRelationUser(Map<String, String> params) {
        Integer userId = Integer.parseInt(params.get("userId"));
        Integer start = Integer.parseInt(params.get("start"));
        Integer rows = Integer.parseInt(params.get("rows"));
        Integer type = ObjectTool.numberOrNull(params.get("type"));
        Integer beViewUserId = ObjectTool.numberOrNull(params.get("beViewUserId"));
        if(type == null && (!type.equals(CodeTypeConstant.USER_LIST_TYPE_170) || !type.equals(CodeTypeConstant.USER_LIST_TYPE_171))){
            return JsonTool.genJson(RetEnum.REQUEST_PARAM_ERROR);
        }
        if(beViewUserId == null){
            beViewUserId = userId;  // 可能是查询别人
        }

        Map<String, Object> map = new HashMap<>();
        map.put("userId",beViewUserId);
        map.put("start",start);
        map.put("rows",rows);
        /**
         * 获取好友列表
         */
        List<User> users =  new ArrayList<>();
        if(type.equals(CodeTypeConstant.USER_LIST_TYPE_170)){   // 关注的人
            users = userFollowDao.selectFocusList(map); // 查询我关注的人
        }else if(type.equals(CodeTypeConstant.USER_LIST_TYPE_171)){ // 我的粉丝
            users = userFollowDao.selectFollowerList(map);
        }

        // 读取获取图片的相关配置
        // 获取图片alitool
        String OSS_CDN = configCacheDao.selectByCkey(ConfigConstant.OSS_CDN).getCvalue();
        String ACCESS_ID = configCacheDao.selectByCkey(ConfigConstant.ACCESS_ID).getCvalue();
        String ACCESS_KEY = configCacheDao.selectByCkey(ConfigConstant.ACCESS_KEY).getCvalue();
        String BUCKET_ID = configCacheDao.selectByCkey(ConfigConstant.BUCKET_ID).getCvalue();
        // 查看图片用OSS_CDN
        AliTool aliTool = AliTool.getInstance(OSS_CDN, ACCESS_ID, ACCESS_KEY, BUCKET_ID);

        List<Map<String,Object>> userList = new ArrayList<>();
        for(User user:users){
            Map<String, Object> resultUser = new HashMap<>();
            resultUser.put("userId",user.getId());
            resultUser.put("nickName",user.getNickName());
            String headPortraitUrl = "";
            if(StringUtils.isNotBlank(user.getHeadPortraitId())){   // 获取用户头像图片
                headPortraitUrl = aliTool.getAccessURL(user.getHeadPortraitId());
            }
            resultUser.put("headPortraitUrl",headPortraitUrl);

            // 查询是否互相关注
            Integer isFollowing = 0;    // 是否关注
            Integer isBeFollowing = 0;  // 是否被关注

            // 查询是否也关注我
            Map<String, Object> tempMap = new HashMap<>();
            tempMap.put("userId",userId);
            tempMap.put("followerId",user.getId());
            List<UserFollow> userFollows = userFollowDao.selectHasFollow(tempMap);
            if(userFollows.size() > 0){
                isBeFollowing = 1;      // 已被关注
            }
            tempMap.clear();
            tempMap.put("userId",user.getId());
            tempMap.put("followerId",userId);
            List<UserFollow> userFocus = userFollowDao.selectHasFollow(tempMap);
            if(userFocus.size() > 0){
                isFollowing = 1;        // 已关注
            }

            resultUser.put("isFollowing",isFollowing);
            resultUser.put("isBeFollowing",isBeFollowing);
            userList.add(resultUser);
        }
        Map<String, Object> result = new HashMap<>();
        result.put("userList",userList);
        return JsonTool.genJson(RetEnum.SUCCESS,result);
    }
}
